﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClientUpdater
{
	class Program
	{
		static System.IO.StreamWriter writer;
		/// <summary>
		/// This code closes the existing client application,
		/// deletes its directory,
		/// and replaces the contents with the provided zip
		/// </summary>
		/// <param name="args"></param>
		static void Main(string[] args)
		{
			writer = null;
			try
			{
				if (args.Length < 2)
					throw new Exception("too few arguments");
				// first argument is the existing directory
				String existingDirectory = args[0];
				// second argument is the zip file to deflate
				String zipfile = args[1];
				// let's go
				if (args.Length >= 3)
				{
					writer = new System.IO.StreamWriter("update log.txt");
					WriteLine("ExistingDirectory = " + existingDirectory);
					WriteLine("ZipFile = " + zipfile);

					String[] elems = existingDirectory.Split(System.IO.Path.DirectorySeparatorChar);

					System.Diagnostics.ProcessStartInfo zipStartInfo = new System.Diagnostics.ProcessStartInfo();
					zipStartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
					zipStartInfo.FileName = "7z";
					zipStartInfo.UseShellExecute = false;
					zipStartInfo.Arguments = String.Format("x -y -o\"{0}\" {1}", elems[elems.Length-1], zipfile);
					zipStartInfo.RedirectStandardOutput = false;

					WriteLine("Killing process");
					killProcessByName("SchedulerClientGui");
					WriteLine("Process killed");

					System.Threading.Thread.Sleep(5000);

					WriteLine("Deleting Directory");
					clearDirectory(existingDirectory);
					WriteLine("Directory Clean");

					WriteLine("Unzipping");
					System.Diagnostics.Process zipProcess = System.Diagnostics.Process.Start(zipStartInfo);
					// 30-second timeout
					int count = 300;
					try
					{
						while (count >= 0 && zipProcess.HasExited == false)
						{
							count--;
							System.Threading.Thread.Sleep(100);
						}
						if (zipProcess.HasExited == false)
						{

							zipProcess.CloseMainWindow();
						}
						zipProcess.Dispose();
					}
					catch (Exception)
					{
						throw;
					}
					WriteLine("Done unzipping");

					WriteLine("Start new process");
					System.Diagnostics.ProcessStartInfo clientStartInfo = new System.Diagnostics.ProcessStartInfo();
					clientStartInfo.WorkingDirectory = existingDirectory;
					clientStartInfo.FileName = "SchedulerClientGui.exe";
					clientStartInfo.UseShellExecute = false;
					clientStartInfo.Arguments = String.Empty;
					clientStartInfo.RedirectStandardOutput = true;

					System.Diagnostics.Process clientProcess = System.Diagnostics.Process.Start(clientStartInfo);
					if (clientProcess.HasExited == false)
						writer.WriteLine("Didn't exit right away");
					else
						writer.WriteLine("Exited right away -- possible failure");
					WriteLine("Done starting");

					WriteLine("SUCCESS!");
				}
				else
				{
					System.Diagnostics.ProcessStartInfo selfInfo = new System.Diagnostics.ProcessStartInfo();
					selfInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
					selfInfo.FileName = "ClientUpdater.exe";
					selfInfo.UseShellExecute = false;
					selfInfo.Arguments = String.Format("\"{0}\" \"{1}\" \"{2}\"", args[0], args[1], "true");
					selfInfo.RedirectStandardOutput = true;

					System.Diagnostics.Process myP = System.Diagnostics.Process.Start(selfInfo);
				}
			}
			catch (Exception ex)
			{
				WriteLine("Error: " + ex.Message + " @ " + ex.StackTrace);
				Console.WriteLine(ex.Message);
			}
			finally
			{
				if (writer != null)
					writer.Close();
			}
		}

		static void WriteLine(String msg)
		{
			writer.WriteLine(DateTime.Now.ToString() + " " + msg);
			writer.Flush();
		}

		static void killProcessByName(String name)
		{
			foreach (System.Diagnostics.Process myieprocess in System.Diagnostics.Process.GetProcessesByName(name))
			{
				int timeoutcount = 1000;
				while (timeoutcount >= 0 && myieprocess.HasExited == false)
				{
					myieprocess.CloseMainWindow();
					//myieprocess.Kill();
					System.Threading.Thread.Sleep(100);
					timeoutcount--;
					myieprocess.Refresh();
					//myieprocess.Kill();
				}
				if (myieprocess.HasExited == false)
				{
					myieprocess.Kill();
				}
				myieprocess.Dispose();
			}
		}

		static void clearDirectory(String dir)
		{
			if (System.IO.Directory.Exists(dir))
			{
				System.IO.Directory.Delete(dir, true);
			}
			System.IO.Directory.CreateDirectory(dir);
		}
	}
}
